<?php

namespace common\models\db;

use common\components\Tools;
use Yii;
use yii\helpers\ArrayHelper;
use yii\behaviors\BlameableBehavior;
use yii\behaviors\TimestampBehavior;
use wodrow\yii2wtools\behaviors\Uuid;

/**
 * This is the model class for table "{{%admin_auth_item}}".
 *
 * @author
 *
 * @property AdminAuthAssignment[] $adminAuthAssignments
 * @property User[] $users
 * @property AdminAuthRule $ruleName
 * @property AdminAuthItemChild[] $adminAuthItemChildren
 * @property AdminAuthItemChild[] $adminAuthItemChildren0
 * @property AdminAuthItem[] $children
 * @property AdminAuthItem[] $parents
 * @property AdminMenu[] $adminMenus
 *
 * @property-read array $typeDesc
 */
class AdminAuthItem extends \common\models\db\tables\AdminAuthItem
{
    const TYPE_ROLE = 1;
    const TYPE_ROUTE = 2;

    const GET_TYPE_ROLES = 'alloc_roles';
    const GET_TYPE_PERMISSIONS = 'alloc_permissions';
    const GET_TYPE_ROUTES = 'alloc_routes';

    public function getTypeDesc()
    {
        return [
            self::TYPE_ROLE => "角色",
            self::TYPE_ROUTE => "路由",
        ];
    }

    /**
     * @return array|AdminAuthItem[]|mixed|\yii\db\ActiveRecord[]
     */
    public static function getAllRoles()
    {
        $x = Yii::$app->cache->get("AdminAuthItem-getAllRoles");
        if (!$x){
            $x = self::find()->where(['type' => self::TYPE_ROLE])->all();
            Yii::$app->cache->set("AdminAuthItem-getAllRoles", $x);
        }
        return $x;
    }

    public static function getAllPermissions()
    {
        $x = Yii::$app->cache->get("AdminAuthItem-getAllPermissions");
        if (!$x){
            $x = self::find()->where(['type' => self::TYPE_ROUTE])->andWhere(['not like', 'name', '/%', false])->all();
            Yii::$app->cache->set("AdminAuthItem-getAllPermissions", $x);
        }
        return $x;
    }

    public static function getAllRoutes()
    {
        $x = Yii::$app->cache->get("AdminAuthItem-getAllRoutes");
        if (!$x){
            $x = self::find()->where(['type' => self::TYPE_ROUTE])->andWhere(['like', 'name', '/%', false])->all();
            Yii::$app->cache->set("AdminAuthItem-getAllRoutes", $x);
        }
        return $x;
    }

    /**
     * @param $role
     * @param $get_type
     * @return AdminAuthItemChild[]
     */
    public static function getChildsByRole($role, $get_type)
    {
//        Yii::$app->cache->delete("AdminAuthItemChild-getChilds{$get_type}ByRole-{$role}");
        $childs = Yii::$app->cache->get("AdminAuthItemChild-getChilds{$get_type}ByRole-{$role}");
        if (!$childs){
            $query = AdminAuthItemChild::find()->alias('item_p_c')
                ->joinWith('childAdminAuthItem child')
                ->where(['item_p_c.parent' => $role]);
            switch ($get_type){
                case self::GET_TYPE_PERMISSIONS:
                    $query->andWhere(['child.type' => AdminAuthItem::TYPE_ROUTE])
                        ->andWhere(['not like', 'name', '/%', false]);
                    break;
                case self::GET_TYPE_ROUTES:
                    $query->andWhere(['child.type' => AdminAuthItem::TYPE_ROUTE])
                        ->andWhere(['like', 'name', '/%', false]);
                    break;
                case self::GET_TYPE_ROLES:
                    $query->andWhere(['child.type' => AdminAuthItem::TYPE_ROLE]);
                    break;
                default:
                    Tools::yiiLog($get_type);
                    break;
            }
            $childs = $query
//                ->asArray()
                ->all();
//            Yii::$app->cache->set("AdminAuthItemChild-getChilds{$get_type}ByRole-{$role}", $childs);
        }
        return $childs;
    }

    /**
     * @param $role
     * @param string $get_type
     * @return array
     */
    public static function getChildsMapByRole($role, $get_type)
    {
        $gets = self::getChildsByRole($role, $get_type);
        $names = [];
        foreach ($gets as $k => $v) {
            if (!in_array($v->child, $names))$names["{$v->child}"] = $v->child;
        }
        return $names;
    }

    protected function _deleteCaches()
    {
        Yii::$app->cache->delete("AdminAuthItem-getAllRoles");
        Yii::$app->cache->delete("AdminAuthItem-getAllPermissions");
        Yii::$app->cache->delete("AdminAuthItem-getAllRoutes");
        foreach ($this->adminAuthAssignments as $k => $v) {
            $v->save();
        }
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);
        $this->_deleteCaches();
    }

    public function afterDelete()
    {
        parent::afterDelete(); // TODO: Change the autogenerated stub
        $this->_deleteCaches();
    }

    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            'timestamp' => [
                'class' => TimestampBehavior::class,
//                'createdAtAttribute' => false,
//                'updatedAtAttribute' => false,
            ],
            'blameable' => [
                'class' => BlameableBehavior::class,
                'createdByAttribute' => false,
                'updatedByAttribute' => false,
            ],
            /*'uuid' => [
                'class' => Uuid::class,
                'column' => false,
            ],*/
        ]);
    }

    public function rules()
    {
        $rules = parent::rules();
        /*foreach ($rules as $k => $v) {
            if ($v[1] == 'required'){
                $rules[$k][0] = array_diff($rules[$k][0], ['created_at', 'updated_at', 'created_by', 'updated_by']);
            }
        }*/
        return ArrayHelper::merge($rules, []);
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        $attributeLabels = parent::attributeLabels();
        return ArrayHelper::merge($attributeLabels, []);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAdminAuthAssignments()
    {
        return $this->hasMany(AdminAuthAssignment::className(), ['item_name' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getUsers()
    {
        return $this->hasMany(User::className(), ['id' => 'user_id'])->viaTable('{{%admin_auth_assignment}}', ['item_name' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getRuleName()
    {
        return $this->hasOne(AdminAuthRule::className(), ['name' => 'rule_name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAdminAuthItemChildren()
    {
        return $this->hasMany(AdminAuthItemChild::className(), ['parent' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAdminAuthItemChildren0()
    {
        return $this->hasMany(AdminAuthItemChild::className(), ['child' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getChildren()
    {
        return $this->hasMany(AdminAuthItem::className(), ['name' => 'child'])->viaTable('{{%admin_auth_item_child}}', ['parent' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getParents()
    {
        return $this->hasMany(AdminAuthItem::className(), ['name' => 'parent'])->viaTable('{{%admin_auth_item_child}}', ['child' => 'name']);
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getAdminMenus()
    {
        return $this->hasMany(AdminMenu::className(), ['route' => 'name']);
    }
}
